<script setup lang="ts">
import type { PropType } from 'vue'
import type { IFormItem } from '@/types/index'
import { computed, inject, reactive, ref } from 'vue'
import searchPopover from '@/components/searchForm/searchPopover.vue'

interface IMethods {
  [method: string]: (...params: any) => void
}
interface IPopoverData {
  prop: string
}

const props = defineProps({
  item: {
    type: Object as PropType<IFormItem>,
    required: true,
  },
  remark: Number,
})
const itemValue = computed(() => JSON.parse(JSON.stringify(props.item)))
// 获取父组件方法
const methods = inject<IMethods>('methods', {
  // 默认方法
  doSomething: () => console.warn('父组件未提供 methods'),
})
// 输入框回车事件
function keyupEnter(_item: IFormItem) {
  methods?.search(props.remark)
}
// 输入框粘贴触发popover
const inputRef = ref(null)
const popoverVisible = ref<boolean>(false)
let popoverData = reactive<IPopoverData[]>([])
// 贴贴触发事件
function paste(event: ClipboardEvent) {
  const pasteData = event.clipboardData?.getData('text') || ''
  if (!pasteData)
    return
  if (pasteData.trim().includes('\n')) {
    popoverData = reactive<IPopoverData[]>(
      [...new Set(pasteData.trim()
        .split('\n')
        .filter(val => val.trim()))]
        .map(val => ({ prop: val.trim() })),
    )
    popoverVisible.value = true
  }
}
function change(event: any, item: IFormItem, type: string = 'input') {
  if (type === 'input' && (typeof event === 'string'))
    event = event?.trim()
  if (methods?.changeForm) {
    methods.changeForm(event, item, type)
  }
  else {
    console.warn('请配置表单改变触发方法')
  }
}
function handleType(type: string) {
  const typeEnum = {
    'ColorPicker': 'ColorPicker', // 待确认
    'el-autocomplete': 'input',
    'el-input-number': 'number',
    'numberbox': 'number',
    'el-select-multiple': 'select-multiple',
    'comboboxMultiple': 'select-multiple',
    'el-select': 'select',
    'combobox': 'select',
    'el-radio': 'radio',
    'el-checkbox': 'checkbox',
    'checkbox': 'checkbox',
    'el-input': 'input',
    'el-date-picker': 'date',
    'datebox': 'date',
    'daterange': 'daterange',
    'datetimerange': 'datetimerange',
    'el-progress': 'progress',
    'datetimebox': 'datetime',
    'timespinner': 'time',
    'combotree': 'tree',
    'month': 'month',
    'monthrange': 'monthrange',
    'validatebox': 'validatebox', // 待确认
    'textarea': 'textarea',
    'textbox': 'textarea',
    'week': 'week',
    'year': 'year',
  } as const
  // 首先定义类型
  type ComponentTypeKeys = keyof typeof typeEnum
  const lowerType = type?.toLowerCase() as ComponentTypeKeys
  return typeEnum[lowerType] || type?.toLocaleLowerCase()
}
</script>

<template>
  <div v-if="item" ref="inputRef" class="item">
    <!-- label -->
    <span v-if="itemValue.label" class="label">{{ itemValue.label }}</span>
    <!-- input -->
    <el-input
      v-if="handleType(item.type) === 'input'" v-model="itemValue.value" class="input" clearable
      :placeholder="item.placeholder || undefined" size="small" @keyup.enter="keyupEnter(item)"
      @input="(value: any) => change(value, item)" @paste="paste"
    />

    <!-- number input -->
    <el-input
      v-else-if="handleType(item.type) === 'number'" v-model="itemValue.value" class="input" clearable
      :placeholder="item.placeholder || undefined" size="small" @input="(value: any) => change(value, item, 'number')"
      @keyup.enter="keyupEnter(item)"
    />
    <!-- select -->
    <el-select
      v-else-if="handleType(item.type) === 'select'" v-model="itemValue.value" class="input" clearable
      :placeholder="item.placeholder || undefined" @change="(value: any) => change(value, item, 'select')"
    >
      <el-option v-for="option in item.options" :key="option.value" :label="option.label" :value="option.value" />
    </el-select>
    <!-- select multiple -->
    <el-select
      v-else-if="handleType(item.type) === 'select-multiple'" v-model="itemValue.value" class="input" multiple
      clearable :placeholder="item.placeholder || undefined" @change="(value: any) => change(value, item, 'select-multiple')"
    >
      <el-option v-for="option in item.options" :key="option.value" :label="option.label" :value="option.value" />
    </el-select>
    <!-- 日期类型输入 -->
    <!-- 1.年 -->
    <el-date-picker
      v-else-if="handleType(item.type) === 'year'" v-model="itemValue.value" class="input" type="year"
      format="YYYY" value-format="YYYY" placeholder="year" @change="(value: any) => change(value, item, 'year')"
    />
    <!-- 2.月份 -->
    <el-date-picker
      v-else-if="handleType(item.type) === 'month'" v-model="itemValue.value" class="input" type="month"
      format="YYYY-MM" value-format="YYYY-MM" placeholder="month" @change="(value: any) => change(value, item, 'month')"
    />
    <!-- 3.星期 -->
    <el-date-picker
      v-else-if="handleType(item.type) === 'week'" v-model="itemValue.value" class="input" type="week"
      format="WW" value-format="WW" placeholder="week" @change="(value: any) => change(value, item, 'week')"
    />
    <!-- 4.日期 -->
    <el-date-picker
      v-else-if="handleType(item.type) === 'date'" v-model="itemValue.value" class="input" type="date"
      format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="date" @change="(value: any) => change(value, item, 'date')"
    />
    <!-- 5.日期时间 -->
    <el-date-picker
      v-else-if="handleType(item.type) === 'datetime'" v-model="itemValue.value" class="input" type="datetime"
      format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" placeholder="date"
      @change="(value: any) => change(value, item, 'datetime')"
    />
    <!-- 日期范围类型输入 -->
    <!-- 1.年份范围 组件无法使用 -->
    <!-- <el-date-picker v-else-if="handleType(item.type) === 'yearrange'" v-model="item.value" type="yearrange" format="YYYY"
      value-format="YYYY" range-separator="To"></el-date-picker> -->
    <!-- 2.月份范围 -->
    <el-date-picker
      v-else-if="handleType(item.type) === 'monthrange'" v-model="itemValue.value" class="input"
      type="monthrange" format="YYYY-MM" value-format="YYYY-MM" range-separator="至" start-placeholder="开始"
      end-placeholder="结束" @change="(value: any) => change(value, item, 'monthrange')"
    />
    <!-- 3.日期范围 -->
    <el-date-picker
      v-else-if="handleType(item.type) === 'daterange'" v-model="itemValue.value" class="input" type="daterange"
      format="YYYY-MM-DD" value-format="YYYY-MM-DD" range-separator="至" start-placeholder="开始" end-placeholder="结束"
      @change="(value: any) => change(value, item, 'daterange')"
    />
    <!-- 4.日期时间范围 -->
    <el-date-picker
      v-else-if="handleType(item.type) === 'datetimerange'" v-model="itemValue.value" class="input"
      type="datetimerange" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" range-separator="至"
      start-placeholder="开始" end-placeholder="结束" @change="(value: any) => change(value, item, 'datetimerange')"
    />
    <!-- 粘贴触发弹窗 -->
    <search-popover
      ref="inputRef" class="input" :popover-visible="popoverVisible" :item="item"
      :popover-data="popoverData" @close="popoverVisible = false"
    />
  </div>
</template>

<style scoped lang="scss">
.item {
  display: flex;
  position: relative;
  padding-right: 15px;
  height: 32px;
  flex-wrap: nowrap;
  margin-bottom: 8px;

  .label {
    display: flex;
    justify-content: center;
    align-items: center;
    padding-right: 5px;
    text-wrap: nowrap;
  }

  .input {
    flex-grow: 1;
    width: 168px;
  }
}
</style>
